package com.my.zl.console.common.utils.generator;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.sql.DataSource;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.my.zl.console.common.constant.AutocodeConfigC;
import com.my.zl.console.common.utils.generator.bean.ZLColumn;
import com.my.zl.console.common.utils.generator.bean.ZLConfig;
import com.my.zl.console.common.utils.generator.bean.ZLSequence;
import com.my.zl.console.common.utils.generator.bean.ZLTable;
import com.my.zl.console.dao.generator.GeneratorDao;

import cn.hutool.core.util.StrUtil;
import cn.hutool.db.ds.simple.SimpleDataSource;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component("databaseReader")
public class ReaderDatabase implements ReaderData<ZLConfig> {
    
    private static String DEFAULT_TYPE = "默认分类";
    private static String DEFAULT_ENCODE = "UTF-8";
    private static Pattern TITLE_RULE = Pattern.compile("([ -]){1,}");//标题获取规则
    private static Pattern TITLE_RULE2 = Pattern.compile("(【.*?】)|(\\[.*?\\])");//标题获取规则
    
    @Autowired
    private  Map<String,GeneratorDao> generatorDao;
    @Autowired
    protected DataSource dynamicDataSource;
    
    @Override
    public void parseData(ZLConfig config) throws Exception {
        // TODO Auto-generated method stub
        parseTable(config, true);
    }
    
    @Override
    public Map<String,Object> getData(ZLConfig config) throws Exception {
        // TODO Auto-generated method stub
        Map<String,Object>  result = new HashMap<>();
        
        parseTable(config, false);
        result.put("tables", config.getTbls());

        return result;
    }
    
    public void parseTable(ZLConfig config,boolean tableFlag) throws Exception {
        // TODO Auto-generated method stub
        try{
            GeneratorDao gdao =  null;
            String cdskey = AutocodeConfigC.DDS_KEY + config.getProjectId().toString();
            if(StringUtils.isNotBlank(config.getJdbcUrl())){
                DynamicRoutingDataSource dynamicRoutingDataSource = (DynamicRoutingDataSource)dynamicDataSource;
                if(!dynamicRoutingDataSource.getCurrentDataSources().containsKey(cdskey)){
                    SimpleDataSource dynamicDataSourceVO = new SimpleDataSource(config.getJdbcUrl(), config.getJdbcLoginname(), config.getJdbcPassword());
                    dynamicRoutingDataSource.addDataSource(cdskey, dynamicDataSourceVO);
                }
                DynamicDataSourceContextHolder.push(cdskey);
                gdao =  generatorDao.get(config.getDatabaseType() + AutocodeConfigC.DAO_KEY);
            }else{
                gdao =  generatorDao.get("localSqlDao");
            }
            
            List<String> loadTables = config.getLoadTables();
            if(loadTables != null && loadTables.size()>0){
                List<ZLTable>  tableLists = new ArrayList<>();
                List<String> hasTables =  new ArrayList<>();
                String queryType= StringUtils.isNotBlank(config.getQueryType())?config.getQueryType():"0";
                for(String tableCodes : loadTables){
                    List<ZLTable> tables  = gdao.queryTables(tableCodes, queryType);
                    for(ZLTable tbl : tables){
                        if(hasTables.contains(tbl.getTableCode())){
                            continue;
                        }
                        hasTables.add(tbl.getTableCode());
                        tbl.setTableTag(DEFAULT_TYPE);
                        tbl.setTableName(tbl.getTableCode());//原始编号
                        tbl.setTableCode(tbl.getTableCode().toLowerCase());
                        if(hasTables.contains(tbl.getTableCode())){
                            continue;
                        }
                        hasTables.add(tbl.getTableCode());
                        
                        if(StrUtil.isBlank(tbl.getTableTitle())){
                            tbl.setTableTitle(praseTitleByPattern(tbl.getTableComment(),tbl.getTableCode()));
                        }else{
                            tbl.setTableTitle(praseTitleByPattern(tbl.getTableTitle(),tbl.getTableCode()));
                        }
                        if(tableFlag){
                            List<ZLColumn> columns = gdao.queryTableColumns(tbl.getTableCode());
                            for(ZLColumn col : columns){
                                col.setColumnName(col.getColumnCode());
                                col.setColumnCode(col.getColumnCode().toLowerCase());
                                if(StrUtil.isBlank(col.getColumnTitle())){
                                    col.setColumnTitle(praseTitleByPattern(col.getColumnComment(),col.getColumnCode()));
                                }else{
                                    col.setColumnTitle(praseTitleByPattern(col.getColumnTitle(),col.getColumnCode()));
                                }
                            }
                            tbl.setAllcols(columns); 
                        }
                        
                        tableLists.add(tbl);
                    }
                }
                
                config.setTbls(tableLists);
            }
            
            List<String> loadSeqs = config.getLoadSeqs();
            if(loadSeqs!=null && loadSeqs.size()>0){
                List<ZLSequence>  sequenceLists =  new ArrayList<>();
                
                config.setSeqs(sequenceLists);
            }
        }finally {
            DynamicDataSourceContextHolder.clear();
        }
    }
    
    /** 按规则解析出标题,也可以自定义传入解析规则*/
    private static String praseTitleByPattern(String str,String code){
        if(StringUtils.isBlank(str)){
            return code;
        }
        //优先顺序
        String title = null;
        str = str.toLowerCase();
        if(str.contains(code)){
            str=str.replace(code, "").trim();
        }
        Matcher titleM = TITLE_RULE2.matcher(str);
        if(titleM.find()){
            title = titleM.group();
            title = title.substring(1, title.length()-1);
        }else{
            String[] titleArr = TITLE_RULE.split(str);
            title = titleArr[0].trim();
        }
        if(StringUtils.isNotBlank(title)){
            if(title.length() > 100){
                title =  title.substring(0,100).trim();
            }
            return title;
        }
        return code;
    }
}
